/*
 *  ------------------------------------------------------------------------------
 */
/*
 *  ExternCustomer.java
 */
/*
 *  external customer for ecom application
 */
/*
 *  Fabienne Boyer - Didier Donsez may 2006
 */
/*
 *  ------------------------------------------------------------------------------
 */

package ecom.client;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import ecom.beans.*;

import javax.transaction.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import ecom.pojos.*;

/**
 * Simple customer for the ecom application.
 * 
 * @author Fabienne Boyer
 * @created 10 septembre 2006
 */
public class ExternCustomer {

	int accountId = 0;
	
	Context initialContext = null;
	UserTransaction utx = null;
	 
	 
	public static void main(String[] args) {
		String userEmail = null;
		try {
			System.out.println("Begining Client...");
			parseArgs(args);
			CartLocal cartBean = null;
			// if user don't use jclient/client container
			System
					.setProperty(Context.INITIAL_CONTEXT_FACTORY,
							"org.objectweb.carol.jndi.spi.MultiOrbInitialContextFactory");

			// get JNDI initial context
			Context initialContext = null;
			try {
				initialContext = new InitialContext();
			} catch (Exception e) {
				System.err.println("Cannot get initial context for JNDI: " + e);
				System.exit(2);
			}

			// We want to start transactions from client: get UserTransaction
			UserTransaction utx = null;
			try {
				utx = (UserTransaction) initialContext
						.lookup("javax.transaction.UserTransaction");
			} catch (NamingException e) {
				System.err.println("Cannot lookup UserTransaction: " + e);
				System.exit(2);
			}

			EcomCustomerRemote ecomCustomerBean = null;
			try {
				ecomCustomerBean = (EcomCustomerRemote) initialContext
						.lookup("ecom.beans.EcomCustomerBean" + "_"
								+ EcomCustomerRemote.class.getName()
								+ "@Remote");
			} catch (NamingException e) {
				System.err.println("Cannot get EcomCustomerBean : " + e);
				System.exit(2);
			}

			AuthBeanInterface authBean = null;
			try {
				authBean = (AuthBeanInterface) initialContext
						.lookup("ecom.beans.AuthBean" + "_"
								+ AuthBeanInterface.class.getName() + "@Remote");
			} catch (NamingException e) {
				System.err.println("Cannot get AuthBean : " + e);
				System.exit(2);
			}

			boolean authent = false;
			while (true) {
				try {
					if (!authent) {
						System.out
								.println("------------------------------------------------------\n");
						System.out.println("Enter a command :\n");
						System.out.println("1 = list products");
						System.out.println("2 = list products by category");
						System.out.println("3 = list products by brand");
						System.out.println("4 = list products by keyword");
						System.out
						.println("5 = list the products in your cart ");
						System.out.println("6 = add a product in your cart");
						System.out.println("9 = authentication ");
						System.out.println("10 = ask a technical question about a product");
						System.out.println("11 = view a product's technical questions");
						System.out.println("12 = remove");
						System.out.println("0 = quit the application ");

						int choice = Tx.readInt();

						switch (choice) {
						case 1:
							listProducts(ecomCustomerBean);
							break;
						case 2:
							System.out.println("Enter a product category :");
							String cat = Tx.readString();
							listProductsByCat(ecomCustomerBean, cat);
							break;
						case 3:
							System.out.println("Enter a product brand :");
							String brand = Tx.readString();
							listProductsByBrand(ecomCustomerBean, brand);
							break;
						case 4:
							System.out.println("Enter a product category :");
							String keyword = Tx.readString();
							listProductsByKeyword(ecomCustomerBean, keyword);
							break;
						case 6:
							System.out.println("Enter a product identifier :");
							String productRef = Tx.readString();
							addProductToCart(ecomCustomerBean, productRef);
							break;
						case 5:
							listProductsInCart(ecomCustomerBean);
							break;
						case 9:
							System.out
									.println("Enter the authentication email : ");
							String email = Tx.readString();
							System.out.println("Enter the password : ");
							String pwd = Tx.readString();

							if (authBean.authCustomer(email, pwd)) {
								System.out
										.println("Authentication succeed !\n");
								authent = true;
								userEmail = email;
							} else {
								System.out
										.println("Wrong email or password !\n");
							}
							break;
						case 10:
							System.out.println("Enter a product reference :");
							String ref = Tx.readString();
							System.out.println("Enter your question : ");
							String question = Tx.readString();
							askTechQuestion(ecomCustomerBean, ref,question);
							break;
						case 11:
							System.out.println("Enter a product reference :");
							String ref2 = Tx.readString();
							listTechQuestions(ecomCustomerBean, ref2);
							break;
						case 12:
							System.out.println("Enter a product reference :");
							String ref3 = Tx.readString();
							ecomCustomerBean.cartRemove(ref3);
							//listTechQuestions(ecomCustomerBean, ref2);
							break;
						case 0:
							System.exit(0);
							break;
						default:
							System.out.println("Unknown operation.");
						}

					} else {
						System.out
								.println("------------------------------------------------------\n");
						System.out.println("Enter a command :\n");
						System.out.println("1 = list products");
						System.out.println("2 = list products by category");
						System.out.println("3 = list products by brand");
						System.out.println("4 = list products by keyword");
						System.out.println("5 = add a product in your cart");
						System.out
								.println("6 = list the products in your cart ");
						System.out
								.println("7 = buy the products in your cart ");
						System.out
								.println("8 = get the balance of an account ");
						System.out.println("9 = ask a technical question about a product");
						System.out.println("10 = view a product's technical questions");
						System.out.println("0 = quit the application ");

						int choice = Tx.readInt();

						switch (choice) {
						case 1:
							listProducts(ecomCustomerBean);
							break;
						case 2:
							System.out.println("Enter a product category :");
							String cat = Tx.readString();
							listProductsByCat(ecomCustomerBean, cat);
							break;
						case 3:
							System.out.println("Enter a product brand :");
							String brand = Tx.readString();
							listProductsByBrand(ecomCustomerBean, brand);
							break;
						case 4:
							System.out.println("Enter a product category :");
							String keyword = Tx.readString();
							listProductsByKeyword(ecomCustomerBean, keyword);
							break;
						case 5:
							System.out.println("Enter a product reference :");
							String productRef = Tx.readString();
							addProductToCart(ecomCustomerBean, productRef);
							break;
						case 6:
							listProductsInCart(ecomCustomerBean);
							break;

						case 7:
							/*System.out.println("Give your account number ");
							int accountId = Tx.readInt();*/
							
							buyCart(ecomCustomerBean, userEmail);
							break;

						case 0:
							System.exit(0);
							break;
						case 9:
							System.out.println("Enter a product reference :");
							String ref = Tx.readString();
							System.out.println("Enter your question : ");
							String question = Tx.readString();
							askTechQuestion(ecomCustomerBean, ref,question);
							break;
							
						case 10:
							System.out.println("Enter a product reference :");
							String ref2 = Tx.readString();
							listTechQuestions(ecomCustomerBean, ref2);
							break;
						default:
							System.out.println("Unknown operation.");
						}

					}

				} catch (Exception e) {
					e.printStackTrace(System.err);
				}
			}
		} catch (Exception e) {
			System.err.println("Client get an exception " + e);
			System.exit(2);
		}
	}

	private static void listTechQuestions(EcomCustomerRemote ecomCustomerBean,
			String ref) {
		Vector<TechQuestion> res = ecomCustomerBean.getTechQuestions(ref);
		Iterator<TechQuestion> ite = res.iterator();
		while (ite.hasNext()) {
			TechQuestion cur = ite.next();
			System.out.println("Q : "+cur.getQuestion());
			if (cur.getReponse() != null) System.out.println("A : "+cur.getReponse());
			System.out.println("---");
		}
	}

	private static void askTechQuestion(EcomCustomerRemote ecomCustomerBean, String ref, String question) {
		ecomCustomerBean.createTechQuestion(ref,question);
	}

	private static void listProductsByKeyword(
			EcomCustomerRemote ecomCustomerBean, String keyword) {
		try {
			Vector<Product> prods = ecomCustomerBean
					.getProductsByKeyword(keyword);
			Iterator<Product> ite = prods.iterator();

			System.out
					.println("|Ref\t|Brand\t|Name\t|Description\t|Price\t|NbQuestions\t|");
			while (ite.hasNext()) {
				Product cur = ite.next();
				System.out.println("|" + cur.getReference() + "\t|"
						+ cur.getMarque() + "\t|" + cur.getName() + "\t|"
						+ cur.getDescription() + "\t|" + cur.getEuroPrice()
						+ "\t|" + cur.getNbQuestions() + "\t|");
			}

			// to be implemented
		} catch (Exception e) {
			System.err.println("Exception getting product list: " + e);
		}
	}

	private static void listProductsByBrand(
			EcomCustomerRemote ecomCustomerBean, String brand) {
		try {
			Vector<Product> prods = ecomCustomerBean.getProductsByBrand(brand);
			Iterator<Product> ite = prods.iterator();

			System.out
					.println("|Ref\t|Brand\t|Name\t|Description\t|Price\t|NbQuestions\t|");
			while (ite.hasNext()) {
				Product cur = ite.next();
				System.out.println("|" + cur.getReference() + "\t|"
						+ cur.getMarque() + "\t|" + cur.getName() + "\t|"
						+ cur.getDescription() + "\t|" + cur.getEuroPrice()
						+ "\t|" + cur.getNbQuestions() + "\t|");
			}

			// to be implemented
		} catch (Exception e) {
			System.err.println("Exception getting product list: " + e);
		}
	}

	private static void listProductsByCat(EcomCustomerRemote ecomCustomerBean,
			String cat) {
		try {
			Vector<Product> prods = ecomCustomerBean.getProductsByCat(cat);
			Iterator<Product> ite = prods.iterator();

			System.out
					.println("|Ref\t|Brand\t|Name\t|Description\t|Price\t|NbQuestions\t|");
			while (ite.hasNext()) {
				Product cur = ite.next();
				System.out.println("|" + cur.getReference() + "\t|"
						+ cur.getMarque() + "\t|" + cur.getName() + "\t|"
						+ cur.getDescription() + "\t|" + cur.getEuroPrice()
						+ "\t|" + cur.getNbQuestions() + "\t|");
			}

			// to be implemented
		} catch (Exception e) {
			System.err.println("Exception getting product list: " + e);
		}
	}

	/**
	 * list the product of the store
	 * 
	 * @param ecomCustomerBean
	 *            Description of the Parameter
	 */
	private static void listProducts(EcomCustomerRemote ecomCustomerBean) {
		try {
			Vector<Product> prods = ecomCustomerBean.getAllProducts();
			Iterator<Product> ite = prods.iterator();

			System.out
					.println("|Ref\t|Brand\t|Name\t|Description\t|Price\t|Stock\t|");
			while (ite.hasNext()) {
				Product cur = ite.next();
				System.out.println("|" + cur.getReference() + "\t|"
						+ cur.getMarque() + "\t|" + cur.getName() + "\t|"
						+ cur.getDescription() + "\t|" + cur.getEuroPrice()
						+ "\t|" + cur.getStock() + "\t|");
			}

			// to be implemented
		} catch (Exception e) {
			System.err.println("Exception getting product list: " + e);
		}
	}

	/**
	 * list the products added in the cart
	 * 
	 * @param cartBean
	 *            the bean
	 */
	private static void listProductsInCart(EcomCustomerRemote ecomCustomerBean) {
		try {
			Vector<Product> prods = ecomCustomerBean.cartListProduct();
			
			Iterator<Product> ite = prods.iterator();
			
			while(ite.hasNext()) System.out.println(ite.next().getName());
			
		} catch (Exception e) {
			System.err.println("Exception getting product list: " + e);
		}
	}

	/**
	 * add a product in the cart
	 * 
	 * @param ecomCustomerBean
	 *            the bean
	 * @param productId
	 *            the id of the product to add
	 */
	private static void addProductToCart(EcomCustomerRemote ecomCustomerBean,
			String productId) {
		try {
			ecomCustomerBean.cartAddProduct(productId);
			
			} catch (Exception e) {
			System.err.println("Exception adding product : " + productId + " "
					+ e);
		}

	}

	/**
	 * buy the cart
	 * 
	 * @param ecomCustomerBean
	 *            Description of the Parameter
	 * @param accountId
	 *            Description of the Parameter
	 */
	private static void buyCart(EcomCustomerRemote ecomCustomerBean,
			String email) {
		try {
			if (ecomCustomerBean.cartOrder(email)) System.out.println("ok");
			else System.out.println("not ok !");
			
		} catch (Exception e) {
			System.err.println("Exception buying product : " + e);
		}

	}

	/**
	 * Parses an argument list for an acountId
	 * 
	 * @param args
	 *            Description of the Parameter
	 */

	static void parseArgs(String args[]) {
		if ((args == null) || (args.length == 0)) {
			return;
		}
		// for (int i = 0; i < args.length; i++) {
		// if (args[i].equals("-id")) {
		// accountId = new Integer(args[++i]);
		// }
	}

	/**
	 * Description of the Method
	 * 
	 * @param sb
	 *            Description of the Parameter
	 * @param objs
	 *            Description of the Parameter
	 */
	static void formatObjectArray(StringBuffer sb, Object[] objs) {
		if ((objs == null) || (objs.length == 0)) {
			return;
		}
		for (int i = 0; i < objs.length; i++) {
			if (i != 0) {
				sb.append(':');
			}
			sb.append(objs[i].toString());
		}
		sb.append('\n');
	}

	/**
	 * Description of the Method
	 * 
	 * @param sb
	 *            Description of the Parameter
	 * @param objs
	 *            Description of the Parameter
	 * @param format
	 *            Description of the Parameter
	 */
	static void formatObjectArray(StringBuffer sb, Object[] objs, String format) {
		if ((objs == null) || (objs.length == 0)) {
			return;
		}
		sb.append(java.text.MessageFormat.format(format, objs));
	}
}
